package com.quest.parallelDesign;

import com.quest.parallelDesign.entity.*;

import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;

/**
 * 用CompletableFuture完成了我们对多组任务并行执行，但是其依然是依赖我们的线程池，在我们的线程池中使用的是阻塞队列，
 * 也就是当我们某个线程执行完任务的时候需要通过这个阻塞队列进行，那么肯定会发生竞争，所以在JDK1.7中提供了ForkJoinTask和ForkJoinPool。
 *
 * Fork/Join框架：就是在必要的情况下，将一个大任务，进行拆分(fork)成若干个小任务(拆到不可再拆时)，再将一个个的小任务运算的结果进行Join汇总。
 * ForkJoinPool中每个线程都有自己的工作队列，并且采用Work-Steal算法防止线程饥饿。
 * Worker线程用LIFO的方法取出任务，但是会用FIFO的方法去偷取别人队列的任务，这样就减少了锁的冲突。
 *
 * 我们定义一个OrderTask并且定义五个获取信息的任务，在compute中分别fork执行这五个任务，最后在将这五个任务的结果通过Join获得，最后完成我们的并行化的需求。
 */
public class OrderTask extends RecursiveTask<OrderInfo> {
    @Override
    protected OrderInfo compute() {
        long start = System.currentTimeMillis();
        System.out.println("执行" + this.getClass().getSimpleName() + "线程名字为:" + Thread.currentThread().getName());
        // 定义其他五种并行TasK
        CustomerTask customerTask = new CustomerTask();
        TenantTask tenantTask = new TenantTask();
        DiscountTask discountTask = new DiscountTask();
        FoodTask foodTask = new FoodTask();
        OtherTask otherTask = new OtherTask();

        invokeAll(customerTask, tenantTask, discountTask, foodTask, otherTask);
        OrderInfo orderInfo = new OrderInfo(customerTask.join(), discountTask.join(), foodTask.join(), tenantTask.join(), otherTask.join());
        System.out.println("主线程："+ Thread.currentThread().getName()+" ,总耗时："+(System.currentTimeMillis()-start));
        return orderInfo;
    }

    public static void main(String[] args) {
        ForkJoinPool forkJoinPool = new ForkJoinPool(Runtime.getRuntime().availableProcessors() - 1);
        System.out.println(forkJoinPool.invoke(new OrderTask()));
    }
}

    class CustomerTask extends RecursiveTask<CustomerInfo> {

        @Override
        protected CustomerInfo compute() {
            System.out.println("执行" + this.getClass().getSimpleName() + "线程名字为:" + Thread.currentThread().getName());
            return new CustomerInfo();
        }
    }

    class TenantTask extends RecursiveTask<TenantInfo> {

        @Override
        protected TenantInfo compute() {
            System.out.println("执行" + this.getClass().getSimpleName() + "线程名字为:" + Thread.currentThread().getName());
            return new TenantInfo();
        }
    }

    class DiscountTask extends RecursiveTask<DiscountInfo> {

        @Override
        protected DiscountInfo compute() {
            System.out.println("执行" + this.getClass().getSimpleName() + "线程名字为:" + Thread.currentThread().getName());
            return new DiscountInfo();
        }
    }

    class FoodTask extends RecursiveTask<FoodListInfo> {

        @Override
        protected FoodListInfo compute() {
            System.out.println("执行" + this.getClass().getSimpleName() + "线程名字为:" + Thread.currentThread().getName());
            return new FoodListInfo();
        }
    }

    class OtherTask extends RecursiveTask<OtherInfo> {

        @Override
        protected OtherInfo compute() {
            System.out.println("执行" + this.getClass().getSimpleName() + "线程名字为:" + Thread.currentThread().getName());
            return new OtherInfo();
        }
    }
